/**
 * Server
 * 
 * 29/12/2013
 * 
 * Copyright GPL
 */
package com.jtmproject.bluetooth;

import com.jtmproject.GameActivity;
import com.jtmproject.IServer;
import com.jtmproject.PongGame;
import com.jtmproject.R;
import com.jtmproject.World;
import com.jtmproject.classes.ClientMessages;
import com.jtmproject.classes.SerializeUtils;
import com.jtmproject.classes.StringUtils;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

/**
 * This class is to communicate with the clients
 * 
 * @author Javier Tejedor
 * @thanks Google
 */
public class Server implements IServer {
	
	//message types sent from the BluetoothChatService Handler
	public static final int MESSAGE_STATE_CHANGE = 1;
	public static final int MESSAGE_READ = 2;
	public static final int MESSAGE_WRITE = 3;
	public static final int MESSAGE_DEVICE_NAME = 4;
	public static final int MESSAGE_TOAST = 5;

	//key names received from the BluetoothChatService Handler
	public static final String DEVICE_NAME = "device_name";
	public static final String TOAST = "toast";

	private StringBuffer outStringBuffer;
	private BluetoothAdapter bluetoothAdapter = null;
	private ServiceServer serviceServer = null;

	private ClientMessages clientMessages;
	private Activity activity;
	
	/**
	 * this stores a copy of Server object 
	 * to share this object between activities  
	 */
	private static Server server;

	/**
	 * constructor
	 * @param activity
	 */
	public Server(Activity activity){
		this.activity = activity;
		bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

		if (bluetoothAdapter == null) {
			Toast.makeText(
					activity, 
					R.string.bluetooth_not_available, 
					Toast.LENGTH_LONG).show();
			activity.finish();
			return;
		}

		activateBluetooth();
		setStateServer();
		
		clientMessages = new ClientMessages();
	}

	/**
	 * this activates the bluetooth
	 */
	private void activateBluetooth() {
		if (!bluetoothAdapter.isEnabled()) {
			bluetoothAdapter.enable();
			
			//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			//to improve this code
			while(bluetoothAdapter.isEnabled() == false){ 
				//this waits to enable the bluetooth
			}

			setupCommunication();

		} else {
			if (serviceServer == null){
				setupCommunication();
			} 
		}
	}

	/**
	 * this start the server only if it is not started yet
	 */
	private void setStateServer() {
		if (serviceServer != null) {
			if (serviceServer.getState() == ServiceServer.STATE_NONE) {
				serviceServer.start();
			}
		}
	}

	/**
	 * this sets up the communication with the client
	 */
	private void setupCommunication() {
		
		serviceServer = new ServiceServer(handlerToCommunicate);
		outStringBuffer = new StringBuffer("");
		
	}
	
    /**
     * sends a message.
     * @param message  A string of text to send.
     */
    public void sendMessage(String message) {

        if (serviceServer.getState() != ServiceServer.STATE_CONNECTED) {
            Toast.makeText(activity, 
            		R.string.not_connected, 
            		Toast.LENGTH_SHORT).show();
        }else{

            if (message.length() > 0) {

                byte[] send = message.getBytes();
                serviceServer.write(send);
                outStringBuffer.setLength(0);
                
            }
        }
    }
    
    /**
     * this sends a class serialized 
     * @param classSerialized
     */
    private void sendClassSerialized(byte[] classSerialized){
    	if(classSerialized.length > 0){
    		serviceServer.write(classSerialized);
    	}
    }

	/* (non-Javadoc)
	 * @see com.jtmproject.IServer#cancelConnection()
	 */
    @Override
	public void cancelConnection(){
		if (serviceServer != null){
			serviceServer.stop();
		} 

		if(bluetoothAdapter.isEnabled()){
			bluetoothAdapter.disable();
		}
	}
	
	/* (non-Javadoc)
	 * @see 
	 * com.jtmproject.IServer#sendClassWorldSerialized(com.jtmproject.World)
	 */
    @Override
	public void sendClassWorldSerialized(World world){
		sendClassSerialized(SerializeUtils.serialize(world));
	}
    
	@Override
	public void sendCancelConnection() {
		this.sendMessage(Client.CANCEL_CONNECTION);
	}

    /**
     * handler to communicate with the client
     */
    private final Handler handlerToCommunicate = new Handler() {
    	
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            
            case MESSAGE_STATE_CHANGE:
            	
                switch (msg.arg1) {
                case ServiceServer.STATE_CONNECTED:
                    break;
                case ServiceServer.STATE_CONNECTING:
                    break;
                case ServiceServer.STATE_LISTEN:
                case ServiceServer.STATE_NONE:
                    break;
                }
                
                break;
                
            case MESSAGE_WRITE:

                //byte[] writeBuf = (byte[]) msg.obj;
                //String writeMessage = new String(writeBuf);
                
                break;
                
            case MESSAGE_READ:

                byte[] readBuf = (byte[]) msg.obj;

                String readMessage = new String(readBuf, 0, msg.arg1);
                
                if(readMessage.equals(Client.START_GAME)){
                	
                	Server.this.sendMessage(Client.START_GAME);
                	startGame();
                	
                } else {
                	
                	if(StringUtils.canParseToFloat(readMessage)){

                    	if(PongGame.getWorld() != null){
                    		 clientMessages.setMoveXPaddleB(
                    				 Float.parseFloat(readMessage));
                    	}
 
                    	readMessage = null;
                    	readBuf = null;
                	}
                }
 
                break;
                
            case MESSAGE_DEVICE_NAME:
                
                break;
                
            case MESSAGE_TOAST:
                
                break;
            }
        }

		/**
		 * this starts the game
		 */
		private void startGame() {
			Intent intent = new Intent(activity, GameActivity.class);
			intent.putExtra(GameActivity.TYPE_GAMER, PongGame.SERVER);
			activity.startActivity(intent);
			
			activity.finish();
		}
    };
	
	/**
	 * returns this server
	 * @return
	 */
	public static Server getServer() {
		return server;
	}

	/**
	 * sets this server
	 * @param server
	 */
	public static void setServer(Server server) {
		Server.server = server;
	}
	
	/* (non-Javadoc)
	 * @see com.jtmproject.IServer#getMoveXB()
	 */
	public float getMoveXB() {
		return clientMessages.getMoveXPaddleB();
	}

}
